<?php

namespace RedMVC;

/**
 * File class
 *
 * @category    RedMVC
 * @author      Jan Fischer, bitWorking <info@bitworking.de>
 */
class File{

    const REMOTE_DATA_METHOD_CURL   = 0;
    const REMOTE_DATA_METHOD_SOCKET = 1;
    const REMOTE_DATA_METHOD_FILE   = 2;    

    /**
     * get remote data from url
     *
     * @param string $url
     * @param int $timeout
     * @param int $method (see constants)
     * @return string
     */
    public static function getRemoteData($url, $timeout = 10, $method = self::REMOTE_DATA_METHOD_CURL){        
        if($method === self::REMOTE_DATA_METHOD_CURL){
            if(!function_exists('curl_exec')){
                throw new \Exception('File: could not get remote data (curl not installed)');
            }
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_URL, $url);
            //WARNING: this prevents curl from detecting a 'man in the middle' attack
            curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
            $data = curl_exec($ch);
            if(curl_errno($ch)){                
                throw new \Exception('File: could not get remote data (curl): '.curl_error($ch));
            }
            curl_close($ch);
            return $data;
        }
        else if($method === self::REMOTE_DATA_METHOD_FILE){
            ini_set('default_socket_timeout', $timeout);
            $ctx = stream_context_create(array(
                'http' => array(
                    'timeout' => $timeout
                )
            ));
            if(!$data = file_get_contents($url, 0, $ctx)){
                throw new \Exception('File: could not get remote data (file_get_contents)');
            }
            return $data;
        }
        else if($method === self::REMOTE_DATA_METHOD_SOCKET){
            $urlParts   = parse_url($url);
            $host       = $urlParts['host'];
            if(isset($urlParts['scheme']) && strtolower($urlParts['scheme']) === 'https'){
                $host = 'ssl://'.$urlParts['host'];
                $urlParts['port'] = 443;
            }
            if(!isset($urlParts['port'])){
                $urlParts['port'] = 80;
            }
            $fp = @fsockopen($host, $urlParts['port'], $errno, $errstr, $timeout);
            if(!$fp){
                throw new \Exception('File: could not get remote data (fsockopen): '.$errstr);
            }
            stream_set_timeout($fp, $timeout);
            $get = '/';
            if(isset($urlParts['path'])){
                if(isset($urlParts['query'])){
                    $get = "$urlParts[path]?$urlParts[query]";
                }
                else{
                    $get = $urlParts['path'];
                }
            }  
            $out = "GET $get HTTP/1.0\r\n";
            $out .= "Host: $urlParts[host]\r\n";
            $out .= "Connection: Close\r\n\r\n";
			fwrite($fp, $out);
            $response = '';  
            while(!feof($fp)){
                $response .= fgets($fp, 128);
            }  
            fclose($fp);
            // split headers from data  
            $responseSplit = explode("\r\n\r\n", $response, 2);            
            return $responseSplit[1];
        }
    }

    /**
     * convert file path to url
     *
     * @param string $file
     * @param bool $absoluteUrl
     * @return string
     */
    public static function toBrowser($file, $absoluteUrl = false){
        if(strtolower(substr($file, 0, 4)) == 'http'){
            return $file;
        }
        $request    = Registry::get('RedMVC_Request');
        $file       = str_replace(PUBLIC_PATH, '', $file);
        $file       = str_replace($request->getBaseUrl(), '', $file);
        $file       = str_replace("\\", '/', $file);        
        if($absoluteUrl){
            return $request->getRootUrl().$file;
        }
        return $request->getBaseUrl().$file;
    }

    /**
     * file download dialog
     *
     * @param string $file
     * @param string|NULL $name
     */
    public static function download($file, $name = null){
        $bits = file_get_contents($file);
        if(!$bits || strlen($bits) == 0) {
            throw new \Exception('File: file not found');
        }
        $filename = (null === $name) ? basename($file) : $name;
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: anytextexeptno-cache', true);
        header('Pragma: public');
        header('Content-Length: '.filesize($file));
        echo $bits;
        die();
    }

}